package com.sr.security;

import com.sr.enums.ResponseCode;
import com.sr.exception.Assert;
import org.springframework.security.authentication.AuthenticationProvider;
import org.springframework.security.authentication.BadCredentialsException;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;

/** 登录验证并创建令牌
 * @author xiaochi
 * @date 2022/5/2 17:24
 * @desc JwtAuthenticationProvider
 */
public class JwtAuthenticationProvider implements AuthenticationProvider {

    private UserDetailService userDetailService;
    private BCryptPasswordEncoder bCryptPasswordEncoder;

    public JwtAuthenticationProvider(UserDetailService userDetailService,BCryptPasswordEncoder bCryptPasswordEncoder){
        this.userDetailService = userDetailService;
        this.bCryptPasswordEncoder = bCryptPasswordEncoder;
    }

    /**
     * 登录验证
     * @param authentication
     * @return
     * @throws AuthenticationException
     */
    @Override
    public Authentication authenticate(Authentication authentication) throws AuthenticationException {
        String username = authentication.getName();
        Assert.assertNotNull(username,ResponseCode.SYSTEM_USERNAME_NOT_EMPTY.getMessage());
        Assert.assertNotNull(authentication.getCredentials(),new UsernameNotFoundException(ResponseCode.SYSTEM_PASSWORD_ERROR.getMessage()));
        String password = authentication.getCredentials().toString();
        UserDetails userDetails = this.userDetailService.loadUserByUsername(username);
        Assert.isTure(bCryptPasswordEncoder.matches(password,userDetails.getPassword()),new BadCredentialsException(ResponseCode.SYSTEM_PASSWORD_ERROR.getMessage()));
        return new JwtAuthenticationToken(userDetails,userDetails.getPassword(),userDetails.getAuthorities());
    }

    /**
     * 验证令牌类型
     * @param authentication
     * @return
     */
    @Override
    public boolean supports(Class<?> authentication) {
        return authentication.equals(JwtAuthenticationToken.class);
    }
}
